home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre2.z / postgre2 / doc / papers / design_of_post next >
Encoding:
Text File  |  1992-08-27  |  80.5 KB  |  1,999 lines

  1. .nr tp 12
  2. .nr sp 12
  3. .nr pp 11
  4. .nr fp 10
  5. .sz \n(pp
  6. .fo ''%''
  7. .(l C
  8. .sz \n(sp
  9. .b
  10. THE DESIGN OF POSTGRES
  11. .sz \n(pp
  12. .sp 3
  13. .i
  14. Michael Stonebraker and Lawrence A. Rowe
  15. .sp
  16. Department of Electrical Engineering
  17. and Computer Sciences
  18. University of California
  19. Berkeley, CA 94720
  20. .sp
  21. .r
  22. .)l
  23. .sp 3
  24. .ce
  25. .uh Abstract
  26. .pp
  27. This paper presents the preliminary design of a new
  28. database management system, called POSTGRES, 
  29. that is the successor to the INGRES relational database system.  
  30. The main design goals of the new system are to:
  31. .in +8n
  32. .sp
  33. .ti -3n
  34. 1)\ provide better support for complex objects,
  35. .sp 0.5v
  36. .ti -3n
  37. 2)\ provide user extendibility for data types, operators and access methods,
  38. .sp 0.5v
  39. .ti -3n
  40. 3)\ provide facilities for active databases (i.e., alerters and
  41. triggers) and inferencing including forward- and backward-chaining,
  42. .sp 0.5v
  43. .ti -3n
  44. 4)\ simplify the DBMS code for crash recovery,
  45. .sp 0.5v
  46. .ti -3n
  47. 5)\ produce a design that can take advantage of
  48. optical disks, workstations composed of multiple tightly-coupled processors,
  49. and custom designed VLSI chips, and
  50. .sp 0.5v
  51. .ti -3n
  52. 6)\ make as few changes as possible (preferably none) to the relational model.
  53. .sp
  54. .in -8n
  55. The paper describes the query language, programming
  56. langauge interface, system architecture, query processing strategy, and storage system
  57. for the new system.
  58. .sh 1  "INTRODUCTION"
  59. .pp
  60. The INGRES relational database management system (DBMS)
  61. was implemented during 1975-1977 at the Univerisity of California.  
  62. Since 1978 various prototype
  63. extensions have been made to support distributed databases [STON83a],
  64. ordered relations [STON83b], abstract data types [STON83c],
  65. and QUEL as a data type [STON84a].  In addition, we proposed but never prototyped
  66. a new application program interface [STON84b].  
  67. The University of California version of INGRES
  68. has been ``hacked up enough'' to make the inclusion of substantial new 
  69. function extremely difficult.  
  70. Another problem with continuing to extend the existing system
  71. is that many of our proposed ideas would be difficult to 
  72. integrate into that system because of earlier design decisions.
  73. Consequently, we are building a new database system, called POSTGRES (POST
  74. inGRES).  
  75. .pp
  76. This paper describes the design rationale, 
  77. the features of POSTGRES, and our proposed implementation for the system.
  78. The next section discusses the design goals for the system.
  79. Sections 3 and 4 presents the query language and programming
  80. language interface, respectively, to the system.
  81. Section 5 describes the system architecture including
  82. the process structure, query processing strategies, and storage
  83. system.
  84. .sh 1  "DISCUSSION OF DESIGN GOALS"
  85. .pp
  86. The relational data model has proven very successful at
  87. solving most business data processing problems. 
  88. Many commercial systems are being marketed that are
  89. based on the relational model and in time these systems
  90. will replace older technology DBMS's.
  91. However, there are many engineering applications (e.g., CAD systems, programming environments,
  92. geographic data, and graphics) for which a conventional relational system
  93. is not suitable.
  94. We have embarked on the design and implementation of a new
  95. generation of DBMS's, based on the relational model, that will
  96. provide the facilities required by  these applications.
  97. This section describes the major design goals for this new system.
  98. .pp
  99. The first goal is to support complex objects [LORI83, STON83c].
  100. Engineering data, in contrast to business data, 
  101. is more complex and dynamic.
  102. Although the required data types can be simulated on a relational system, the
  103. performance of the applications is unacceptable.
  104. Consider the following simple example.
  105. The objective is to store a collection of geographic objects in a
  106. database (e.g., polygons, lines, and circles).  In a conventional
  107. relational DBMS, a relation for each type of object
  108. with appropriate fields would be created:
  109. .(b
  110. POLYGON (id, other fields)
  111. CIRCLE (id, other fields)
  112. LINE (id, other fields)
  113. .)b
  114. To display these objects on the
  115. screen would require additional information that represented
  116. display characteristics for each object (e.g., color, position,
  117. scaling factor, etc.).  
  118. Because this information is the same for all objects, it
  119. can be stored in a single relation:
  120. .(b
  121. DISPLAY( color, position, scaling, obj-type, object-id)
  122. .)b
  123. The ``object-id'' field is the identifier of a tuple in
  124. a relation identified by the ``obj-type'' field (i.e., POLYGON,
  125. CIRCLE, or LINE).
  126. Given this representation, the following commands would have to be executed
  127. to produce a display:
  128. .(b
  129. foreach OBJ in {POLYGON, CIRCLE, LINE} do
  130.     range of O is OBJ
  131.     range of D is DISPLAY
  132.     retrieve (D.all, O.all)
  133.     where D.object-id = O.id
  134.     and D.obj-type = OBJ
  135. .)b
  136. Unfortunately, this collection of commands will not be executed
  137. fast enough by any relational system to ``paint the screen'' in 
  138. real time (i.e., one or two seconds).
  139. The problem is that regardless of how fast your DBMS is there are
  140. too many queries that have to be executed to fetch the data for the object.
  141. The feature that is needed is the ability to store the object 
  142. in a field in DISPLAY so that only one query is required to fetch it.
  143. Consequently, our first goal is to correct this deficiency.
  144. .pp
  145. The second goal for POSTGRES is to make it easier to extend the
  146. DBMS so that it can be used in new application domains.
  147. A conventional DBMS has a small set of built-in data types and
  148. access methods.
  149. Many applications require specialized data types (e.g., geometic
  150. data types for CAD/CAM or a latitude and longitude position data
  151. type for mapping applications).
  152. While these data types can be simulated on the built-in data types,
  153. the resulting queries are verbose and confusing and the performance
  154. can be poor.
  155. A simple example using boxes is presented elsewhere [STON86].
  156. Such applications would be best served by the ability to
  157. add new data types and new operators to a DBMS.  
  158. Moreover, B-trees are only appropriate for certain kinds of data, 
  159. and new access methods are often required for some data types.  
  160. For example, K-D-B trees [ROBI81] and R-trees [GUTM84] 
  161. are appropriate access methods for point and polygon data, 
  162. respectively.  
  163. .pp
  164. Consequently, our second goal is to allow new data types, new operators and
  165. new access methods to be included in the DBMS.  Moreover, it is crucial 
  166. that they be implementable by non-experts which means easy-to-use 
  167. interfaces should be preserved for any code that will be written by a user.
  168. Other researchers are pursuing a similar goal [DEWI85].
  169. .pp
  170. The third goal for POSTGRES is to support active databases and rules.
  171. Many applications are most easily programmed using alerters and triggers.   
  172. For example, form-flow applications such as a bug reporting system
  173. require active forms that are passed from one user to another [TSIC82, ROWE82].
  174. In a bug report application, the manager of the program maintenance group
  175. should be notified if a high priority bug that has been assigned to a programmer
  176. has not been fixed by a specified date.
  177. A database alerter is needed that will send a message to the manager calling
  178. his attention to the problem.
  179. Triggers can be used to propagate updates in the database to maintain 
  180. consistency.
  181. For example, deleting a department tuple in the DEPT relation
  182. might trigger an update to delete all employees in that department 
  183. in the EMP relation.
  184. .pp
  185. In addition, many expert system applications operate on data
  186. that is more easily described as rules rather than as data values.  
  187. For example, the teaching load of professors 
  188. in the EECS department can be described by the following rules:
  189. .in +8n
  190. .sp 0.5v
  191. .ti -3n
  192. 1)\ The normal load is 8 contact hours per year
  193. .sp 0.5v
  194. .ti -3n
  195. 2)\ The scheduling officer gets a 25 percent reduction
  196. .sp 0.5v
  197. .ti -3n
  198. 3)\ The chairman does not have to teach
  199. .sp 0.5v
  200. .ti -3n
  201. 4)\ Faculty on research leave receive a reduction proportional to their leave fraction
  202. .sp 0.5v
  203. .ti -3n
  204. 5)\ Courses with less than 10 students generate credit at 0.1 contact hours per student
  205. .sp 0.5v
  206. .ti -3n
  207. 6)\ Courses with more than 50 students generate EXTRA contact hours at a rate of
  208. 0.01 per student in excess of 50 
  209. .sp 0.5v
  210. .ti -3n
  211. 7)\ Faculty can have a credit balance or a deficit of up to 2 contact hours
  212. .sp
  213. .in -8n
  214. These rules are subject to frequent change.  
  215. The leave status, course assignments, and administrative assignments
  216. (e.g., chairman and scheduling officer) all change frequently.  
  217. It would be most natural to store
  218. the above rules in a DBMS and then infer the actual teaching load of
  219. individual faculty rather than storing teaching load as ordinary data
  220. and then attempting to enforce the above rules by a collection of
  221. complex integrity constraints.
  222. Consequently, our third goal is to support alerters, triggers, and general rule processing.
  223. .pp
  224. The fourth goal for POSTGRES is to reduce the amount of code in the DBMS written
  225. to support crash recovery.
  226. Most DBMS's have a large amount of crash recovery code that
  227. is tricky to write, full of special cases, and very difficult to test and debug.  
  228. Because one of our goals is to allow user-defined access methods, it is imperative
  229. that the model for crash recovery be as simple as possible and easily extendible.
  230. Our proposed approach is to treat the log as normal data managed by the
  231. DBMS which will simplify the recovery code and simultaneously provide
  232. support for access to the historical data.
  233. .pp
  234. Our next goal is to make use of new technologies whenever possible.
  235. Optical disks (even writable optical disks) are becoming available 
  236. in the commercial marketplace.
  237. Although they have slower access characteristics, 
  238. their price-performance and reliability may prove attractive.
  239. A system design that includes optical disks in the
  240. storage hierarchy will have an advantage.
  241. Another technology that we forsee is workstation-sized processors with
  242. several CPU's.  
  243. We want to design POSTGRES in such way as to take advantage of these
  244. CPU resources.
  245. Lastly, a design that could utilize special purpose hardware effectively might
  246. make a convincing case for designing and implementing custom designed VLSI chips.
  247. Our fifth goal, then, is to investigate a design that 
  248. can effectively utilize an optical disk, several tightly 
  249. coupled processors and custom designed VLSI chips.
  250. .pp
  251. The last goal for POSTGRES is to make as few
  252. changes to the relational model as possible.  
  253. First, many users in the business data processing world 
  254. will become familiar with relational concepts and  
  255. this framework should be preserved if possible.  
  256. Second, we believe the original ``spartan simplicity'' argument made by Codd
  257. [CODD70] is as true today as in 1970.  
  258. Lastly, there are many semantic data models but there does not appear to
  259. be a small model that will solve everyone's problem.
  260. For example, a generalization hierarchy will not solve the problem of structuring
  261. CAD data and the design models developed by the CAD community will not
  262. handle generalization hierarchies.
  263. Rather than building a system that is based on a large, complex data model,
  264. we believe a new system should be built on a small, simple model that is
  265. extendible.
  266. We believe that we can accomplish our goals
  267. while preserving the relational model.  
  268. Other researchers are striving for similar goals but 
  269. they are using different approaches
  270. [AFSA85, ATKI84, COPE84, DERR85, LORI83, LUM85]
  271. .pp
  272. The remainder of the paper describes the design of POSTGRES and the basic
  273. system architecture we propose to use to implement the system.
  274. .sh 1  "POSTQUEL"
  275. .pp
  276. This section describes the query language supported by POSTGRES.
  277. The relational model as described in the original definition by Codd [CODD70] has been
  278. preserved.
  279. A database is composed of a collection of relations that contain tuples with the same
  280. fields defined, and the values in a field have the same data type.
  281. The query language is based on the INGRES query language QUEL [HELD75].
  282. Several extensions and changes have been made to QUEL
  283. so the new language is called POSTQUEL to distinguish
  284. it from the original language and other QUEL extensions described
  285. elsewhere [STON85a, KUNG84].  
  286. .pp
  287. Most of QUEL is left intact.
  288. The following commands are included in POSTQUEL without any changes:
  289. Create Relation,
  290. Destroy Relation,
  291. Append, 
  292. Delete, 
  293. Replace, 
  294. Retrieve, 
  295. Retrieve into Result, 
  296. Define View, 
  297. Define Integrity, 
  298. and 
  299. Define Protection.
  300. The Modify command which specified the storage structure for a relation has
  301. been omitted because all relations are stored in a particular 
  302. structure designed to support historical data.
  303. The Index command is retained so that other access paths to the data can be defined.
  304. .pp
  305. Although the basic structure of POSTQUEL is very similar to QUEL, numerous
  306. extensions have been made to support complex objects, user-defined data types
  307. and access methods, time varying data (i.e., versions, snapshots, and historical data),
  308. iteration queries, alerters, triggers, and rules.
  309. These changes are described in the subsections that follow.  
  310. .sh 2  "Data Definition"
  311. .pp
  312. The following built-in data types are provided;
  313. .in +8n
  314. .sp
  315. .ti -3n
  316. 1)\ integers,
  317. .sp +0.5v
  318. .ti -3n
  319. 2)\ floating point,
  320. .sp +0.5v
  321. .ti -3n
  322. 3) fixed length character strings,
  323. .sp +0.5v
  324. .ti -3n
  325. 4)\ unbounded varying length arrays of fixed
  326. types with an arbitrary number of dimensions,
  327. .sp +0.5v
  328. .ti -3n
  329. 5) POSTQUEL, and
  330. .sp +0.5v
  331. .ti -3n
  332. 6)\ procedure.
  333. .sp
  334. .in -8n
  335. Scalar type fields (e.g., integer, floating point, and fixed length character
  336. strings) are referenced by the conventional dot notation (e.g., EMP.name).
  337. .pp
  338. Variable length arrays are provided for applications that need to store large
  339. homogenous sequences of data (e.g., signal processing data, image, or voice).
  340. Fields of this type are referenced in the standard way (e.g., EMP.picture[i] 
  341. refers to the i-th element of the picture array).
  342. A special case of arrays is the text data type which is a one-dimensional
  343. array of characters.
  344. Note that arrays can be extended dynamically.
  345. .pp
  346. Fields of type POSTQUEL contain a sequence of data manipulation commands.
  347. They are referenced by the conventional dot notation.
  348. However, if a POSTQUEL field contains a retrieve command, the data specified
  349. by that command can be implicitly referenced by a multiple dot notation
  350. (e.g., EMP.hobbies.battingavg) as proposed elsewhere [STON84a] and first
  351. suggested by Zaniolo in GEM [ZANI83].
  352. .pp
  353. Fields of type procedure contain procedures written in a general purpose programming
  354. language with embedded data manipulation commands (e.g., EQUEL [ALLM76]
  355. or Rigel [ROWE79]).
  356. Fields of type procedure and POSTQUEL can be executed using the Execute command.
  357. Suppose we are given a relation with the following definition
  358. .(b
  359. EMP(name, age, salary, hobbies, dept)
  360. .)b
  361. in which the ``hobbies'' field is of type POSTQUEL.
  362. That is, ``hobbies'' contains queries that retrieve data about the
  363. employee's hobbies from other relations.
  364. The following command will execute the queries in that field:
  365. .(b
  366. execute (EMP.hobbies)
  367. where EMP.name = ``Smith''
  368. .)b
  369. The value returned by this command can be a sequence of tuples with varying types
  370. because the field can contain more than one retrieve command and different commands
  371. can return different types of records.
  372. Consequently, the programming language interface must provide facilities to determine
  373. the type of the returned records and to access the fields dynamically.
  374. .pp
  375. Fields of type POSTQUEL and procedure can be used to represent complex objects
  376. with shared subobjects and to support multiple representations of data.
  377. Examples are given in the next section on complex objects.
  378. .pp
  379. In addition to these built-in data types, user-defined data types can be defined
  380. using an interface similar to the one developed for ADT-INGRES [STON83c, STON86].
  381. New data types and operators can be defined with the 
  382. user-defined data type facility.
  383. .sh 2 "Complex Objects"
  384. .pp
  385. This section describes how fields of type POSTQUEL and procedure can be
  386. used to represent shared complex objects and to support multiple representations of
  387. data.
  388. .pp
  389. Shared complex objects can be represented by a field of type POSTQUEL that contains
  390. a sequence of commands to retrieve data from other relations that represent the
  391. subobjects.
  392. For example, given the relations POLYGON, CIRCLE, and LINE defined above, an
  393. object relation can be defined that represents complex objects composed of
  394. polygons, circles, and lines.
  395. The definition of the object relation would be:
  396. .(b
  397. create OBJECT (name = char[10], obj = postquel)
  398. .)b
  399. The table in figure 1 shows sample values for this relation.
  400. .(z
  401. .hl
  402. .TS
  403. center;
  404. l | l.
  405. \fBName    OBJ\fP
  406. _
  407. apple    T{
  408. .nf
  409. retrieve (POLYGON.all)
  410. where POLYGON.id = 10
  411. retrieve (CIRCLE.all)
  412. where CIRCLE.id = 40
  413. T}
  414. _
  415. orange    T{
  416. .nf
  417. retrieve (LINE.all)
  418. where LINE.id = 17
  419. retrieve (POLYGON.all)
  420. where POLYGON.id = 10
  421. T}
  422. .TE
  423. .sp
  424. .ce
  425. Figure 1. Example of an OBJECT relation.
  426. .hl
  427. .)z
  428. The relation contains the description of two complex objects named ``apple''
  429. and ``orange.''
  430. The object ``apple'' is composed of a polygon and a circle and the object ``orange''
  431. is composed of a line and a polygon.
  432. Notice that both objects share the polygon with id equal to 10.
  433. .pp
  434. Multiple representations of data are useful for caching data in a data structure
  435. that is better suited to a particular use while still retaining the ease
  436. of access via a relational representation.
  437. Many examples of this use are found in database systems (e.g., main memory relation
  438. descriptors) and forms systems [ROWE85].
  439. Multiple representations can be supported by defining a procedure
  440. that translates one representation (e.g., a relational representation)
  441. to another representation (e.g., a display list suitable for a graphics display).
  442. The translation procedure is stored in the database.
  443. Continuing with our complex object example, the OBJECT relation would
  444. have an additional field, named ``display,'' that would contain a procedure that
  445. creates a display list for an object stored in POLYGON, CIRCLE, and LINE:
  446. .(b
  447. create OBJECT(name=char[10], obj=postquel, display=cproc)
  448. .)b
  449. The value stored in the display field is a procedure written in C
  450. that queries the database to fetch the subobjects that make up the object
  451. and that creates the display list representation for the object.
  452. .pp
  453. This solution has two problems:
  454. the code is repeated in every OBJECT tuple and
  455. the C procedure replicates the queries stored in the
  456. object field to retrieve the subobjects.
  457. These problems can be solved by storing the procedure in a separate
  458. relation (i.e., normalizing the database design) and by
  459. passing the object to the procedure as an argument.
  460. The definition of the relation in which the procedures will be
  461. stored is:
  462. .(b
  463. create OBJPROC(name=char[12], proc=cproc)
  464. append to OBJPROC(name=``display-list'', proc=``...source code...'')
  465. .)b
  466. Now, the entry in the display field for the ``apple'' object is
  467. .(b
  468. execute (OBJPROC.proc)
  469. with (``apple'')
  470. where OBJPROC.name=``display-list''
  471. .)b
  472. This command executes the procedure to create the alternative representation
  473. and passes to it the name of the object.
  474. Notice that the ``display'' field can be changed to a value of type POSTQUEL
  475. because we are not storing the procedure in OBJECT, only a command to
  476. execute the procedure.
  477. At this point, the procedure can execute a command to fetch the data.
  478. Because the procedure was passed the name of the object it can execute
  479. the following command to fetch its value:
  480. .(b
  481. execute (OBJECT.obj)
  482. where OBJECT.name=\fIargument\fP
  483. .)b
  484. This solution is somewhat complex but it stores only one copy of the procedure's
  485. source code in the database and it stores only one copy of
  486. the commands to fetch the data that represents the object.
  487. .pp
  488. Fields of type POSTQUEL and procedure can be efficiently supported through a
  489. combination of compilation and precomputation described in sections 4 and 5.
  490. .sh 2 "Time Varying Data"
  491. .pp
  492. POSTQUEL allows users to save and query historical data and versions [KATZ85, WOOD83].
  493. By default, data in a relation is never deleted or updated.
  494. Conventional retrievals always access the current tuples in the relation.
  495. Historical data can be accessed by indicating the desired time when defining a 
  496. tuple variable.
  497. For example, to access historical employee data a user writes
  498. .(b
  499. retrieve (E.all)
  500. from E in EMP[``7 January 1985'']
  501. .)b
  502. which retrieves all records for employees that worked for the company on 7 January 1985.
  503. The From-clause which is similar to the SQL mechanism to define tuple variables [ASTR76],
  504. replaces the QUEL Range command.
  505. The Range command was removed from the query language because it defined a tuple
  506. variable for the duration of the current user program.
  507. Because queries can be stored as the value of a field, the scope of tuple variable
  508. definitions must be constrained.
  509. The From-clause makes the scope of the definition the current query.
  510. .pp
  511. This bracket notation for accessing historical data implicitly defines a snapshot
  512. [ADIB80].
  513. The implementation of queries that access this snapshot, described in
  514. detail in section 5, searches back through the
  515. history of the relation to find the appropriate tuples.
  516. The user can materialize the snapshot by executing a Retrieve-into command that
  517. will make a copy of the data in another relation.
  518. .pp
  519. Applications that do not want to save historical data can specify a cutoff point
  520. for a relation.
  521. Data that is older than the cutoff point is deleted from the database.
  522. Cutoff points are defined by the Discard command.
  523. The command
  524. .(b
  525. discard EMP before ``1 week''
  526. .)b
  527. deletes data in the EMP relation that is more than 1 week old.
  528. The commands
  529. .(b
  530. discard EMP before ``now''
  531. .)b
  532. and
  533. .(b
  534. discard EMP
  535. .)b
  536. retain only the current data in EMP.
  537. .pp
  538. It is also possible to write queries that reference data which is valid between two dates.
  539. The notation 
  540. .(b
  541. relation-name[date1, date2]
  542. .)b
  543. specifies the relation containing all tuples that were in the relation at some time between
  544. date1 and date2.
  545. Either or both of these dates can be omitted to specify all data in the relation
  546. from the time it was created until a fixed date (i.e., relation-name[,date]),
  547. all data in the relation from a fixed date to the present (i.e., relation-name[date,]),
  548. or all data that was every in the relation (i.e., relation-name[\ ]).
  549. For example, the query
  550. .(b
  551. retrieve (E.all)
  552. from E in EMP[\ ]
  553. where E.name=``Smith''
  554. .)b
  555. returns all information on employees named Smith who worked for the
  556. company at any time.
  557. .pp
  558. POSTQUEL has a three level memory hierarchy: 1) main memory, 2) 
  559. secondary memory (magnetic disk), and 3) tertiary memory (optical disk).
  560. Current data is stored in secondary memory and historical data migrates
  561. to tertiary memory.
  562. However, users can query the data without having to know where the
  563. data is stored.
  564. .pp
  565. Finally, POSTGRES provides support for versions.
  566. A version can be created from a relation or a snapshot.
  567. Updates to a version do not modify the underlying relation and
  568. updates to the underlying relation will be visible through
  569. the version unless the value has been modified in the version.
  570. Versions are defined by the Newversion command.
  571. The command
  572. .(b
  573. newversion EMPTEST from EMP
  574. .)b
  575. creates a version named EMPTEST that is derived from the 
  576. EMP relation.
  577. If the user wants to create a version that is not changed by subsequent
  578. updates to the underlying relation as in most source code control systems
  579. [TICH82], he can create a version off a snapshot.
  580. .pp
  581. A Merge command is provided that will merge the changes made in a version
  582. back into the underlying relation.
  583. An example of a Merge command is
  584. .(b
  585. merge EMPTEST into EMP
  586. .)b
  587. The Merge command will use a semi-automatic procedure to resolve 
  588. updates to the underlying relation and the version that conflict [GARC84].
  589. .pp
  590. This section described POSTGRES support for time varying data.
  591. The strategy for implementing these features is described below in the
  592. section on system architecture.
  593. .sh 2 "Iteration Queries, Alerters, Triggers, and Rules"
  594. .pp
  595. This section describes the POSTQUEL commands for specifying iterative execution
  596. of queries, alerters [BUNE79], triggers [ASTR76], and rules.
  597. .pp
  598. Iterative queries are requried to support transitive closure [GUTM84 KUNG84].
  599. Iteration is specified by appending an asterisk (``*'') to a command that
  600. should be repetitively executed.
  601. For example, to construct a relation that includes all people managed by
  602. someone either directly or indirectly a Retrieve*-into command is used.
  603. Suppose one is given an employee relation with a name and manager field:
  604. .(b
  605. create EMP(name=char[20],...,mgr=char[20],...)
  606. .)b
  607. The following query creates a relation that conatins all employees who
  608. work for Jones:
  609. .(b
  610. retrieve* into SUBORDINATES(E.name, E.mgr)
  611. from E in EMP, S in SUBORDINATES
  612. where E.name=``Jones''
  613.    or E.mgr=S.name
  614. .)b
  615. This command continues to execute the Retrieve-into command until there are
  616. no changes made to the SUBORDINATES relation.
  617. .pp
  618. The ``*'' modifier can be appended to any of the POSTQUEL data manipulation
  619. commands: Append, Delete, Execute, Replace, Retrieve, and Retrieve-into.
  620. Complex iterations, like the A-* heuristic search algorithm, 
  621. can be specified using sequences of these iteration queries [STON85b].
  622. .pp
  623. Alerters and triggers are specified by adding the keyword ``always'' to a query.
  624. For example, an alerter is specified by a Retrieve command such as
  625. .(b
  626. retrieve always (EMP.all)
  627. where EMP.name = ``Bill''
  628. .)b
  629. This command returns data to the application program that issued it whenever Bill's employee
  630. record is changed.\**
  631. .(f
  632. \** Strictly speaking the data is returned to the program through a portal
  633. which is defined in section 4.
  634. .)f
  635. A trigger is an update query (i.e., Append, Replace, or Delete command) with an
  636. ``always'' keyword.
  637. For example, the command
  638. .(b
  639. delete always DEPT
  640. where count(EMP.name by DEPT.dname 
  641.         where EMP.dept = DEPT.dname) = 0
  642. .)b
  643. defines a trigger that will delete DEPT records for departments with no employees.
  644. .pp
  645. Iteration queries differ from alerters and triggers
  646. in that iteration queries run until they cease to have
  647. an effect while alerters and triggers run indefinitely.
  648. An efficient mechanism to awaken ``always'' commands is described in the system architecture
  649. section.
  650. .pp
  651. ``Always'' commands support a forward-chaining control structure in which an update
  652. wakes up a collection of alerters and triggers that can wake up other commands.
  653. This process terminates when no new commands are awakened.
  654. POSTGRES also provides support for a backward-chaining control structure.
  655. .pp
  656. The conventional approach to supporting inference is to extend the view mechanism 
  657. (or something equivalent) with additional capabilities (e.g. [ULLM85, WONG84, JARK85]). 
  658. The canonical example is the definition of the ANCESTOR
  659. relation based on a stored relation PARENT:
  660. .(b
  661. PARENT (parent-of, offspring)
  662. .)b
  663. Ancestor can then be defined by the following commands:
  664. .(b
  665. range of P is PARENT
  666. range of A is ANCESTOR
  667. define view  ANCESTOR (P.all)
  668. define view* ANCESTOR (A.parent-of, P.offspring)
  669.             where A.offspring = P.parent-of
  670. .)b
  671. Notice that the ANCESTOR view is defined by multiple commands
  672. that may involve recursion.
  673. A query such as:
  674. .(b
  675. retrieve (ANCESTOR. parent-of) 
  676. where ANCESTOR.offspring = ``Bill''
  677. .)b
  678. is processed by extensions to a standard query 
  679. modification algorithm [STON75]
  680. to generate a recursive command or a sequence of commands on stored 
  681. relations.  
  682. To support this mechanism, the 
  683. query optimizer must be extended to handle these commands.
  684. .pp
  685. This approach works well when there are only a few commands which define
  686. a particular view and when the commands do not generate conflicting
  687. answers.
  688. This approach is less successful if either of these conditions is
  689. violated as in the following example:
  690. .(b
  691. define view DESK-EMP (EMP.all, desk = ``steel'') where EMP.age < 40
  692. define view DESK-EMP (EMP.all, desk = ``wood'' where EMP.age >= 40
  693. define view DESK-EMP (EMP.all, desk = ``wood'') where EMP.name = ``hotshot''
  694. define view DESK-EMP (EMP.all, desk = ``steel'') where EMP.name = ``bigshot''
  695. .)b
  696. In this example, employees over 40 get a wood desk, those 
  697. under 40 get a steel desk.
  698. However, ``hotshot'' and ``bigshot'' are exceptions to these rules.
  699. ``Hotshot'' is given a wood desk and ``bigshot'' is given 
  700. a steel desk, regardless of their ages.  
  701. In this case, the query:
  702. .(b
  703. retrieve (DESK-EMP.desk) where DESK-EMP.name = ``bigshot''
  704. .)b
  705. will require 4 separate commands to be optimized and run.  Moreover, both
  706. the second and the fourth definitions produce an answer to the query that
  707. is different.
  708. In the case that a larger number of view definitions is
  709. used in the specification of an object, then the important performance
  710. parameter will be isolating the view definitions which are actually
  711. useful.  Moreover, when there are conflicting view definitions (e.g. the general
  712. rule and then exceptional cases), one requires a priority scheme to 
  713. decide which of conflicting definitions to utilize.  
  714. The scheme 
  715. described below works well in such
  716. situations.
  717. .pp
  718. POSTGRES supports backward-chaining rules by virtual columns (i.e., columns for which
  719. no value is stored).
  720. Data in such columns is inferred on demand from rules and cannot be directly 
  721. updated, except by adding or dropping rules.
  722. Rules are specified by adding the keyword ``demand'' to a query.
  723. Hence, for the DESK-EMP example, the EMP relation would have a virtual
  724. field, named ``desk,'' that would be defined by four rules:
  725. .(b
  726. replace demand EMP (desk = ``steel'') where EMP.age < 40
  727. replace demand EMP (desk = ``wood'' where EMP.age >= 40
  728. replace demand EMP (desk = ``wood'') where EMP.name = ``hotshot''
  729. replace demand EMP (desk = ``steel'') where EMP.name = ``bigshot''
  730. .)b
  731. The third and fourth commands would be defined at a higher priority than
  732. the first and second.  
  733. A query that accessed the desk field would cause the ``demand'' commands 
  734. to be processed to determine the appropriate desk value for each EMP tuple retrieved.
  735. .pp
  736. This subsection has described a collection of facilities provided in POSTQUEL
  737. to support complex queries (e.g., iteration) and active databases (e.g., alerters,
  738. triggers, and rules).
  739. Efficient techniques for implementing these facilities are given in section 5. 
  740. .sh 1 "PROGRAMMING LANGUAGE INTERFACE"
  741. .pp
  742. This section describes the programming language interface
  743. (HITCHING POST) to POSTGRES.
  744. We had three objectives when designing the HITCHING POST and POSTGRES
  745. facilities.
  746. First, we wanted to design and implement a mechanism that 
  747. would simplify the development of browsing style applications.
  748. Second, we wanted HITCHING POST to be powerful enough that all
  749. programs that need to access the database including the
  750. ad hoc terminal monitor and any preprocessors for embedded
  751. query languages could be written with the interface.
  752. And lastly, we wanted to provide facilities that would allow
  753. an application developer to tune the performance of his program
  754. (i.e., to trade flexibility and reliability for performance).
  755. .pp
  756. Any POSTQUEL command can be executed in a program.
  757. In addition, a mechanism, called a ``portal,'' is provided 
  758. that allows the program to retrieve data from the database.
  759. A portal is similar to a cursor [ASTR76],
  760. except that it allows random access to the data
  761. specified by the query and the
  762. program can fetch more than one record at a time.
  763. The portal mechanism described here is different than the one
  764. we previously designed [STON84b], but the goal
  765. is still the same.
  766. The following subsections describe
  767. the commands for defining portals and accessing data through them and
  768. the facilities for improving the performance of query execution (i.e., 
  769. compilation and fast-path).
  770. .sh 2 "Portals"
  771. .pp
  772. A portal is defined by a Retrieve-portal or Execute-portal
  773. command.
  774. For example, the following command defines a portal named P:
  775. .(b
  776. retrieve portal P(EMP.all)
  777. where EMP.age < 40
  778. .)b
  779. This command is passed to the backend process which generates a
  780. query plan to fetch the data.
  781. The program can now issue commands to fetch data from the backend process
  782. to the frontend process or to change the ``current position'' of the portal.
  783. The portal can be thought of as a query plan in execution in the DBMS process
  784. and a buffer containing fetched data in the application process.
  785. .pp
  786. The program fetches data from the backend into the buffer 
  787. by executing a Fetch command.
  788. For example, the command
  789. .(b
  790. fetch 20 into P
  791. .)b
  792. fetches the first twenty records in the portal into the frontend program.
  793. These records can be accessed by subscript and field references on P.
  794. For example, P[i] refers to the i-th record returned by the last Fetch
  795. command and P[i].name refers to the ``name'' field in the i-th record.
  796. Subsequent fetches replace the previously fetched data in the frontend
  797. program buffer.
  798. .pp
  799. The concept of a portal is that the data in the buffer is the data 
  800. currently being displayed by the browser.
  801. Commands entered by the user at the terminal are translated into database
  802. commands that change the data in the buffer which is then redisplayed.
  803. Suppose, for example, the user entered a command to scroll forward 
  804. half a screen.
  805. This command would be translated by the frontend program (i.e., the browser)
  806. into a Move command followed by a Fetch command.
  807. The following two commands would fetch data into the buffer which when
  808. redisplayed would appear to scroll the data forward by one half screen:
  809. .(b
  810. move P forward 10
  811. fetch 20 into P
  812. .)b
  813. The Move command repositions the ``current position'' to point to the 
  814. 11-th tuple in the portal and the Fetch command fetches tuples 11
  815. through 30 in the ordering established by executing the query plan. 
  816. The ``current position'' of the portal is the first tuple returned by
  817. the last Fetch command.
  818. If Move commands have been executed since the last Fetch command, the
  819. ``current position'' is the first tuple that would be returned by
  820. a Fetch command if it were executed.
  821. .pp
  822. The Move command has other variations that simplify the
  823. implementation of other browsing commands.
  824. Variations exist that allow the portal postion
  825. to be moved forward or backward, to an absolute position, or to the first
  826. tuple that satisfies a predicate.
  827. For example, to scroll backwards one half screen, the following commands
  828. are issued:
  829. .(b
  830. move P backward 10
  831. fetch 20 into P
  832. .)b
  833. In addition to keeping track of the ``current position,'' the backend process
  834. also keeps track of the sequence number of the current tuple so that the program
  835. can move to an absolute position.
  836. For example, to scroll forward to the 63-rd tuple the program executes the command:
  837. .(b
  838. move P forward to 63
  839. .)b
  840. .pp
  841. Lastly, a Move command is provided that will search forward or backward to the
  842. first tuple that satisfies a predicate as illustrated by the following command
  843. that moves forward to the first employee whose salary is greater than $25,000:
  844. .(b
  845. move P forward to salary > 25K
  846. .)b
  847. This command positions the portal on the first qualifying tuple.
  848. A Fetch command will fetch this tuple and the ones immediately following it
  849. which may not satisfy the predicate.
  850. To fetch only tuples that satisfy the predicate, the Fetch command is used
  851. as follows:
  852. .(b
  853. fetch 20 into P where salary > 25K
  854. .)b
  855. The backend process will continue to execute the query plan until 20 tuples have
  856. been found that satisfy the predicate or until the portal data is exhausted.
  857. .pp
  858. Portals differ significantly from cursors in the way data is updated.
  859. Once a cursor is positioned on a record, it can be modified or deleted
  860. (i.e., updated directly).
  861. Data in a portal cannot be updated directly.
  862. It is updated by Delete or Replace commands on the relations from which the
  863. portal data is taken.
  864. Suppose the user entered commands to a browser that change Smith's salary.
  865. Assuming that Smith's record is already in the buffer, the browser would 
  866. translate this request into the following sequence of commands:
  867. .(b
  868. replace EMP(salary=\fINewSalary\fP)
  869. where EMP.name = ``Smith''
  870. fetch 20 into P
  871. .)b
  872. The Replace command modifies Smith's tuple in the EMP relation and the Fetch
  873. command synchronizes the buffer in the browser with the data in the database.
  874. We chose this indirect approach to updating the data 
  875. because it makes sense for the model of a portal as a query plan.
  876. In our previous formulation [STON84], a portal was treated as an ordered
  877. view and updates to the portal were treated as view updates.
  878. We believe both models are viable, although the query plan model requires
  879. less code to be written.
  880. .pp
  881. In addition to the Retrieve-portal command, portals can be defined by an Execute
  882. command.
  883. For example, suppose the EMP relation had a field of type POSTQUEL
  884. named ``hobbies''
  885. .(b
  886. EMP (name, salary, age, hobbies)
  887. .)b
  888. that contained commands to retrieve a person's hobbies from the following
  889. relations:
  890. .(b
  891. SOFTBALL (name, position, batting-avg)
  892. COMPUTERS (name, isowner, brand, interest)
  893. .)b
  894. An application program can define a portal that will range over the tuples
  895. describing a person's hobbies as follows:
  896. .(b
  897. execute portal H(EMP.hobbies)
  898. where EMP.name = ``Smith''
  899. .)b
  900. This command defines a portal, named ``H,'' that is bound to Smith's hobby records.
  901. Since a person can have several hobbies, represented by more than on Retrieve
  902. command in the ``hobbies'' field, the records in the 
  903. buffer may have different types.
  904. Consequently,
  905. HITCHING POST must provide routines that allow the program
  906. to determine the number of fields, and the type, name, 
  907. and value of each field in each record fetched into the buffer.
  908. .sh 2 "Compilation and Fast-Path"
  909. .pp
  910. This subsection describes facilities to improve the performance
  911. of query execution.
  912. Two facilities are provided: query compilation and fast-path.
  913. Any POSTQUEL command, including portal commands, can take advantage of these
  914. facilities.
  915. .pp
  916. POSTGRES has a system catalog in which application programs can store queries
  917. that are to be compiled.
  918. The catalog is named ``CODE'' and has the following structure:
  919. .(b
  920. CODE(id, owner, command)
  921. .)b
  922. The ``id'' and ``owner'' fields form a unique identifier for each stored command.
  923. The ``command'' field holds the command that is to be compiled.
  924. Suppose the programmer of the relation browser described above wanted to 
  925. compile the Replace command that was used to update the employee's salary field.
  926. The program could append the command, with suitable parameters, to the CODE
  927. catalog as follows:
  928. .(b
  929. append to CODE(id=1, owner=``browser'', 
  930.            command=``replace EMP(salary=$1) where EMP.name=$2'')
  931. .)b
  932. ``$1'' and ``$2'' denote the arguments to the command.
  933. Now, to execute the Replace command that updates Smith's salary shown above, the
  934. program executes the following command:
  935. .(b
  936. execute (CODE.command)
  937. with (\fINewSalary\fP, ``Smith'')
  938. where CODE.id=1 and CODE.owner=``browser''
  939. .)b
  940. This command executes the Replace command after substituting
  941. the arguments.
  942. .pp
  943. Executing commands stored in the CODE catalog does not by itself make the command
  944. run any faster.
  945. However, a compilation demon is always executing that examines the entries in the
  946. CODE catalog in every database and compiles the queries.
  947. Assuming the compilation demon has compiled the Replace command in CODE, the query
  948. should run substantially faster because the time to parse and optimize the query is
  949. avoided.
  950. Section 5 describes a general purpose mechanism for invalidating compiled queries
  951. when the schema changes.
  952. .pp
  953. Compiled queries are faster than queries that are parsed and optimized at run-time but
  954. for some applications, even they are not fast enough.
  955. The problem is that the Execute command that invokes the compiled query still
  956. must be processed.
  957. Consequently, a fast-path facility is provided that avoids this overhead.
  958. In the Execute command above, the only variability is the argument list 
  959. and the unique identifier that selects the query to be run.
  960. HITCHING POST has a run-time routine that allows this information to be passed to
  961. the backend in a binary format.
  962. For example, the following function call invokes the Replace command described above:
  963. .(b
  964. exec-fp(1, ``browser'', \fINewSalary\fP, ``Smith'')
  965. .)b
  966. This function sends a message to the backend that includes only the information needed
  967. to determine where each value is located.
  968. The backend retrieves the compiled plan (possibly from the buffer pool),
  969. substitutes the parameters without type checking, and invokes the query plan.
  970. This path through the backend is hand-optimized to be very fast so the
  971. overhead to invoke a compiled query plan is minimal.
  972. .pp
  973. This subsection has described facilities that allow an application programmer to
  974. improve the performance of a program by compiling queries or by using a special
  975. fast-path facility.
  976. .sh 1  "SYSTEM ARCHITECTURE"
  977. .pp
  978. This section describes how we propose to implement POSTGRES.
  979. The first subsection describes the process structure.
  980. The second subsection describes how query processing will be implemented,
  981. including fields of type POSTQUEL, procedure, and user-defined data type.
  982. The third subsection describes how alerters, triggers, and rules will be implemented.
  983. And finally, the fourth subsection describes the storage system for
  984. implementing time varying data.
  985. .sh 2  "Process Structure"
  986. .pp
  987. DBMS code must run as a sparate process from the application programs that
  988. access the database in order to provide data protection.
  989. The process structure can use one DBMS process per application program
  990. (i.e., a process-per-user model [STON81]) or one DBMS process for
  991. all application programs (i.e., a server model).
  992. The server model has many performance benefits 
  993. (e.g., sharing of open file descriptors and buffers and optimized task switching 
  994. and message sending overhead) in a large machine environment in which high
  995. performance is critical.
  996. However, this approach requires that a fairly complete special-purpose
  997. operating system be built.
  998. In constrast, the process-per-user model is simpler to implement but will
  999. not perform as well on most conventional operating systems.
  1000. We decided after much soul searching to implement POSTGRES using a 
  1001. process-per-user model architecture because of our limited programming resources.
  1002. POSTGRES is an ambitious undertaking and we believe the additional complexity
  1003. introduced by the server architecture was not worth the additional risk of not
  1004. getting the system running.
  1005. Our current plan then is to implement POSTGRES as a process-per-user model
  1006. on Unix 4.3 BSD.
  1007. .pp
  1008. The process structure for POSTGRES is shown in figure 3.
  1009. .(z
  1010. .hl
  1011. .nf
  1012. .sp 10v
  1013. .sp
  1014. .ce
  1015. Figure 3. POSTGRES process structure.
  1016. .hl
  1017. .)z
  1018. The POSTMASTER will contain the lock manager (since there are no
  1019. shared segments in 4.3 BSD) and will control the
  1020. demons that will perform various database
  1021. services (such as asynchronously compiling user commands).
  1022. There will be one POSTMASTER process per machine, and it will be started at
  1023. ``sysgen'' time.
  1024. .pp
  1025. The POSTGRES run-time system executes commands on behalf of
  1026. one application program.
  1027. However, a program can have several commands executing at the same
  1028. time.
  1029. The message protocol between the program and backend will use a simple
  1030. request-answer model.
  1031. The request message will have a command designator and a sequence of
  1032. bytes that contain the arguments.
  1033. The answer message format will include a response code and any other data
  1034. requested by the command.
  1035. Notice that in contrast to INGRES [STON76] the backend will not ``load up'' the
  1036. communication channel with data.
  1037. The frontend requests a bounded amount of data with each command.
  1038. .sh 2 "Query Processing"
  1039. .pp
  1040. This section describes the query processing strategies that will
  1041. be implemented in POSTGRES.
  1042. We plan to implement a conventional query optimizer.
  1043. However, three extensions are required to support POSTQUEL.
  1044. First, the query optimizer must be able to take advantage of user-defined
  1045. access methods.
  1046. Second, a general-purpose, efficient mechanism is needed to support fields
  1047. of type POSTQUEL and procedure.
  1048. And third, an efficient mechanism is required to support triggers and rules.
  1049. This section describes our proposed implementation of these mechanisms.
  1050. .sh 3  "Support for New Types"
  1051. .pp
  1052. As noted elsewhere [STON86], existing access methods must be usable for
  1053. new data types, new access methods must be definable, and query
  1054. processing heuristics must be able to optimize plans for which new data types
  1055. and new access methods are present.
  1056. The basic idea is that an access method can support fast access
  1057. for a specific collection of operators.  In the case of B-trees, these operators
  1058. are {<, =, >, >=, <=}.  Moreover, these operators obey a collection
  1059. of rules. Again for B-trees, the rules obeyed by the above set
  1060. of operators is:
  1061. .(b
  1062. P1)   key-1 < key-2 and key-2 < key-3 then key-1 < key-3
  1063. P2)   key-1 < key-2 implies not key-2 < key-1
  1064. P3)   key-1 < key-2 or key-2 < key-1 or key-1 = key-2
  1065. P4)   key-1 <= key-2 if key-1 < key-2 or key-1 = key-2
  1066. P5)   key-1 = key-2 implies key-2 = key-1
  1067. P6)   key-1 > key-2 if key-2 < key-1
  1068. P7)   key-1 >= key-2 if key-2 <= key-1  
  1069. .)b
  1070. A B-tree access method will work for any collection of operators
  1071. that obey the above rules. 
  1072. The protocol for defining new operators will be similar to the one
  1073. described for ADT-INGRES [STON83c].
  1074. Then, a user need simply declare the collection of operators that
  1075. are to be utilized when he builds an index, and a detailed syntax is
  1076. presented in [STON86].
  1077. .pp
  1078. In addition, the query optimizer must be told the performance of the
  1079. various access paths.  
  1080. Following [SELI79], the required
  1081. information will be the number of pages touched and the number of tuples
  1082. examined when processing a clause of the form:
  1083. .(b
  1084. relation.column OPR value
  1085. .)b
  1086. These two values can be included with the 
  1087. definition of each operator, OPR.  The other
  1088. information required is the join selectivity for each
  1089. operator that can participate in a join, and what join processing
  1090. strategies are feasible.  In particular, nested iteration is
  1091. always a feasible strategy, however both merge-join and hash-join 
  1092. work only in restrictive cases.  For each operator, the optimizer must know whether
  1093. merge-join is usable and, if so, what operator to use to sort each
  1094. relation, and whether hash-join is usable.
  1095. Our proposed protocol includes this 
  1096. information with the definition of each operator. 
  1097. .pp
  1098. Consequently, a table-driven query optimizer will be implemented.
  1099. Whenever a user defines new
  1100. operators, the necessary information for the optimizer will be placed in the
  1101. system catalogs which can be accessed by the optimzier.
  1102. For further details, the reader is refered elsewhere [STON86].
  1103. .sh 3  "Support for Procedural Data"
  1104. .pp
  1105. The main performance tactic which we will utilize is precomputing and
  1106. caching the result of procedural data.  This precomputation has
  1107. two steps:
  1108. .(b
  1109. 1) compiling an access plan for POSTQUEL commands
  1110. 2) executing the access plan to produce the answer
  1111. .)b
  1112. When a collection of POSTQUEL commands is executed both of the above steps
  1113. must be performed.  Current systems drop the answer on the floor
  1114. after obtaining it, and have special code to invalidate and recompute
  1115. access plans (e.g. [ASTR76]).  On the other hand, we expect to cache
  1116. both the plan and the answer.  For small answers, we expect to place
  1117. the cached value in the field itself.  For larger answers, we expect to
  1118. put the answer in a relation created for the purpose and then put the name
  1119. of the relation in the field itself where it will serve the role of a
  1120. pointer.  
  1121. .pp
  1122. Moreover, we expect to have a demon which will run in background mode and
  1123. compile plans utilizing otherwise idle time or idle processors.  Whenever
  1124. a value of type procedure is inserted into the database, the run-time
  1125. system will also insert the identity of the user submitting the command.
  1126. Compilation entails checking the protection status of the command, and
  1127. this will be done on behalf of the submitting user.  Whenever, a
  1128. procedural field is executed, the run-time system will ensure that the
  1129. user is authorized to do so.  In the case of ``fast-path,'' the
  1130. run-time system will require that the executing user and defining
  1131. user are the same, so no run-time access to the system catalogs
  1132. is required.
  1133. This same
  1134. demon will also precompute answers.  
  1135. In the most fortunate of cases, access to procedural data is 
  1136. instantaneous because the value of the procedure is cached.  In most
  1137. cases, a previous access plan should be valid sparing the overhead of this
  1138. step.
  1139. .pp
  1140. Both the compiled plan and the answer must be invalidated if necessary.
  1141. The plan must be invalidated if the schema changes inappropriately, while
  1142. the answer must be invalidated if data that it accesses has been changed.
  1143. We now show that this invalidation can be efficiently supported by 
  1144. an extended form of locks.  In a recent paper [STON85c] we have analyzed
  1145. other alternate implementations which can support needed capabilities,
  1146. and the one we will now present was found to be attractive in many situations.
  1147. .pp
  1148. We propose to support a new kind of lock, called an I lock.  The compatibility
  1149. matrix for I locks is shown in figure 4.
  1150. .(z
  1151. .hl
  1152. .(c
  1153. .TS
  1154. c c c c
  1155. l l l l.
  1156.     R    W    I
  1157.  
  1158. R    ok    no    ok
  1159. W    no    no    *
  1160. I    ok    no    ok
  1161. .TE
  1162. .)c
  1163. .sp
  1164. .ce
  1165. Figure 4. Compatibility modes for I locks.
  1166. .hl
  1167. .)z
  1168. When a command is compiled or the answer precomputed, POSTGRES will
  1169. set I locks on all database objects accessed during compilation or
  1170. execution.  These I locks must be persistent (i.e. survive crashes),
  1171. of fine granularity (i.e. on tuples or even fields), escalatable
  1172. to coarser granularity, and correctly
  1173. detect ``phantoms'' [ESWA75].
  1174. In [STON85a], it is suggested that the best way to
  1175. satisfy these goals is to place I locks in data records themselves.
  1176. .pp
  1177. The * in the table in figure 4 indicates that a write lock placed on an
  1178. object containing one or more I locks will simply cause
  1179. the precomputed objects holding the I locks to be
  1180. invalidated.  Consequently, they are called ``invalidate-me'' locks.
  1181. A user can issue a command:
  1182. .(b
  1183. retrieve (relation.I) where qualification
  1184. .)b
  1185. which will return the identifiers of commands
  1186. having I locks on tuples in question.  In this way a user
  1187. can see the consequences of a proposed update.
  1188. .pp
  1189. Fields of type POSTQUEL can be compiled and POSTQUEL fields  with no update statements
  1190. can be precomputed.  Fields of type procedure can be compiled
  1191. and procedures that do not do input/output and do not update the database
  1192. can be precomputed.
  1193. .sh 3  "Alerters, Triggers, and Inference"
  1194. .pp
  1195. This section describes the tactic we will use to implement alerters,
  1196. triggers, and inference.
  1197. .pp
  1198. Alerters and triggers are specified by including the keyword ``always''
  1199. on the command.
  1200. The proposed implementation of ``always'' commands
  1201. is to run the command until it ceases to have an effect.  Then,
  1202. it should be run once more and another special kind of lock set
  1203. on all objects which the commands will read or write.  These T locks
  1204. have the compatibility matrix shown in figure 5.
  1205. .(z
  1206. .hl
  1207. .(c
  1208. .TS
  1209. c c c c c
  1210. l l l l l.
  1211.     R    W    I    T
  1212.  
  1213. R    ok    no    ok    ok
  1214. W    no    no    *    #
  1215. I    ok    no    ok    ok
  1216. T    ok    no    ok    ok
  1217. .TE
  1218. .)c
  1219. .sp
  1220. .ce
  1221. Figure 5. Compatibility modes for T locks.
  1222. .hl
  1223. .)z
  1224. Whenever a transaction writes a data object on which a T-lock has been
  1225. set, the lock manager simply wakes-up the corresponding ``always'' command.
  1226. Dormant ``always'' commands are stored in a system relation in a 
  1227. field of type POSTQUEL.
  1228. As with I locks, T locks must be persistent, of fine granularity and
  1229. escalatable. Moreover, the identity of commands holding T locks can
  1230. be obtained through the special field, T added to all relations. 
  1231. .pp
  1232. Recall that inferencing will be support by virtual fields (i.e., ``demand''
  1233. commands).
  1234. ``Demand'' commands will be implemented similar to the way ``always''
  1235. commands are implemented.
  1236. Each ``demand'' command would be run until
  1237. the collection of objects which it proposes to write are isolated.
  1238. Then a D lock is set on each such object and the command placed in a 
  1239. POSTQUEL field in the system catalogs.
  1240. The compatibility matrix for D locks is shown in figure 6.
  1241. .(z
  1242. .hl
  1243. .(c
  1244. .TS
  1245. c c c c c c
  1246. l l l l l l.
  1247.     R    W    I    T    D
  1248.  
  1249. R    ok    no    ok    ok    &
  1250. W    no    no    *    #    no
  1251. I    ok    no    ok    ok    ok
  1252. T    ok    no    ok    ok    ok
  1253. D    ok    no    *    #    ok
  1254. .TE
  1255. .)c
  1256. .sp
  1257. .ce
  1258. Figure 6. Compatibility modes for D locks.
  1259. .hl
  1260. .)z
  1261. The ``&'' indicates that when a command attempts to read an object on
  1262. which a D lock has been set, the ``demand'' command must be substituted
  1263. into the command being executed using an algorithm similar to query
  1264. modification to produce a new command to execute.  This new command
  1265. represents a subgoal which the POSTGRES system attempts to satisfy.
  1266. If another D lock is encountered, a new subgoal will result, and the
  1267. process will only terminate when a subgoal runs to completion and
  1268. generates an answer.  Moreover, this answer can be cached
  1269. in the field and invalidated when necessary, if the intermediate
  1270. goal commands set I locks as they run.  This process is a database
  1271. version of PROLOG style unification [CLOC81], and supports a backward
  1272. chaining control flow.  The algorithm details appear in [STON85b] along
  1273. with a proposal for a priority scheme.
  1274. .sh 2  "Storage System"
  1275. .pp
  1276. The database will be partly stored on a magnetic disk and partly
  1277. on an archival medium such as an optical
  1278. disk.  Data on magnetic disk includes all secondary
  1279. indexes and recent database tuples.  The optical disk is reserved
  1280. as an archival store containing historical tuples.  There will be 
  1281. a demon which ``vacuums'' tuples from magnetic disk to optical disk
  1282. as a background process.  Data on magnetic disk will be stored using the
  1283. normal UNIX file system with one relation per file.  The optical disk
  1284. will be organized as one large repository with tuples from various
  1285. relations intermixed.  
  1286. .pp
  1287. All relations will be stored as heaps (as in
  1288. [ASTR76]) with an optional collection of secondary indexes.  In addition
  1289. relations can be declared ``nearly ordered,'' and POSTGRES will attempt to
  1290. keep tuples close to sort sequence on some column.
  1291. Lastly, secondary indexes can be defined, which consist of
  1292. two separate physical indexes one for the magnetic disk tuples
  1293. and one for the optical disk tuples, each in a separate
  1294. UNIX file on magnetic disk.  
  1295. Moreover, a secondary index on will automatically be provided for
  1296. all relations on a unique identifier field which is described in
  1297. the next subsection.
  1298. This index will allow any relation to be sequentially
  1299. scanned.
  1300. .sh 3  "Data Format"
  1301. .pp
  1302. Every tuple has an immutable unique identifier (IID) that is assigned
  1303. at tuple creation time and never changes.  This is a 64 bit quantity
  1304. assigned internally by POSTGRES.
  1305. Moreover, each transaction has a unique 64 bit transaction
  1306. identifier (XACTID) assigned by POSTGRES.  
  1307. Lastly, there is a call to a system clock which can return 
  1308. timestamps on demand.  Loosely, these are the current time-of-day.
  1309. .pp
  1310. Tuples will have all non-null fields stored adjacently in a physical
  1311. record.  Moreover, there will be a tuple prefix containing the
  1312. following extra fields:
  1313. .(b
  1314. IID        : immutable id of this tuple
  1315. tmin        : the timestamp at which this tuple becomes valid
  1316. BXID        : the transaction identifier that assigned tmin
  1317. tmax        : the timestamp at which this tuple ceases to be valid
  1318. EXID        : the transaction identifier that assigned tmax
  1319. v-IID        : the immutable id of a tuple in this or some other version
  1320. descriptor    : descriptor on the front of a tuple
  1321. .)b
  1322. The descriptor contains the offset at which
  1323. each non-null field starts, and is similar to the data structure attached
  1324. to System R tuples [ASTR76].  The first transaction identifier and timestamp
  1325. correspond to the timestamp and identifier of the creator of this tuple.
  1326. When the tuple is updated, it is not overwritten; rather the 
  1327. identifier and timestamp of the updating transaction are recorded in
  1328. the second (timestamp, transaction identifier) slot and a new tuple
  1329. is constructed in the database.  The update rules are described in the
  1330. following subsection while the details of version management are deferred 
  1331. to later in the section.
  1332. .sh 3  "Update and Access Rules"
  1333. .pp
  1334. On an insert of a new tuple into a relation, tmin is marked with the
  1335. timestamp of the inserting transaction and its identity is recorded in
  1336. BXID.  When a tuple is deleted, tmax is marked with the timestamp of the
  1337. deleting transaction and its identity is recorded in EXID.  
  1338. An update to a tuple is modelled as an insert followed by a delete. 
  1339. .pp
  1340. To find all the record which have the qualification, QUAL at time T
  1341. the run time system must find all magnetic disk records 
  1342. such that:
  1343. .(b
  1344. 1) tmin < T < tmax and BXID and EXID are committed and QUAL
  1345. 2) tmin < T and tmax = null and BXID is committed and QUAL
  1346. 3) tmin < T and BXID = committed and EXID = not-committed and QUAL 
  1347. .)b
  1348. Then it must find all optical disk
  1349. records satisfying 1). 
  1350. A special transaction log is described below that allows the DBMS
  1351. to determine quickly whether a particular transaction has committed.
  1352. .sh 3  "The POSTGRES Log and Accelerator"
  1353. .pp
  1354. A new XACTID is assigned sequentially to each new transaction.
  1355. When a transaction wishes to commit, 
  1356. all data pages which it has written must be forced out of memory (or
  1357. at least onto stable storage).  Then a single bit is written into the 
  1358. POSTGRES log and an optional transaction accelerator.
  1359. .pp
  1360. Consider three transaction identifiers; T1 which is
  1361. the ``youngest'' transaction identifier which has been assigned,  T2 
  1362. which is a ``young''
  1363. transaction but guaranteed to be older than the oldest active 
  1364. transaction, and T3 which is a ``young'' transaction that is older than
  1365. the oldest committed transaction which wrote data which is
  1366. still on magnetic disk.
  1367. Assume that T1-T3 are recorded in ``secure main memory'' to be
  1368. presently described.
  1369. .pp
  1370. For any transaction with an identifier between T1 and T2, we
  1371. need to
  1372. know which of three states it is in:
  1373. .(b
  1374. 0  = aborted
  1375. 1  = committed
  1376. 2  = in-progress
  1377. .)b
  1378. For any transaction
  1379. with an identifier between T2 and T3, a ``2'' is impossible 
  1380. and the log can be compressed to 1 bit
  1381. per transaction.
  1382. For any transaction older than T3, the vacuum process has 
  1383. written all records to archival storage.  During this vacuuming, the updates
  1384. to all aborted transactions can be discarded, and hence all archival
  1385. records correspond to committed transactions.
  1386. No log need be kept for transactions older than T3.
  1387. .pp
  1388. The proposed log structure is an ordered relation, LOG as follows:
  1389. .(b
  1390. line-id:        the access method supplied ordering field
  1391. bit-1[1000]:    a bit vector
  1392. bit-2[1000]:    a second bit vector
  1393. .)b
  1394. The status of xact number i is recorded in bit (remainder of i divided
  1395. by 1000) of line-id number i/1000.
  1396. .pp
  1397. We assume that several thousand bits (say 1K-10K bytes)
  1398. of ``secure main memory''
  1399. are available for 10-100 blocks comprising the ``tail'' of 
  1400. the log.  
  1401. Such main memory is duplexed or triplexed and supported
  1402. by an uninterruptable power supply.
  1403. The assumed hardware structure for this memory is the 
  1404. following.  Assume a circular
  1405. ``block pool'' of n blocks each of size 2000 bits.  When more space is needed,
  1406. the oldest block is reused.  The hardware maintains a pointer which indicates
  1407. the current largest xact identifier (T1 - the high water mark) and which bit it will use.  it also
  1408. has a second pointer which is the current oldest transaction in the
  1409. buffer (the low water mark) and which bit it 
  1410. points to.  When high-water approaches 
  1411. low-water, a block of the log must be ``reliably'' pushed 
  1412. to disk and joins previously pushed blocks.  Then low-water
  1413. is advanced by 1000.  High-water is advanced every time a new transaction
  1414. is started.  The operations available on the hardware structure are:
  1415. .(b
  1416. advance the high-water (i.e. begin a xact)
  1417. push a block and update low-water
  1418. abort a transaction
  1419. commit a transaction
  1420. .)b
  1421. .pp
  1422. Hopefully, the block pool is big enough to allow all transactions
  1423. in the block to be committed or aborted before the block is ``pushed.''  
  1424. In this
  1425. case, the block will never be updated on disk.  
  1426. If there are long running transactions, then blocks may
  1427. be forced to disk before all transactions are committed or aborted.
  1428. In this
  1429. case, the subsequent commits or aborts will require an update
  1430. to a disk-based block 
  1431. and will be much slower.  Such disk operations on the LOG relation
  1432. must be done by a special transaction (transaction zero) and will follow 
  1433. the normal update
  1434. rules described above.
  1435. .pp
  1436. A trigger will be used to periodically advance T2 and replace
  1437. bit-2 with nulls (which don't consume space) for any log records
  1438. that correspond to transactions now older than T2.
  1439. .pp
  1440. At 5 transactions per second, the LOG relation will require about
  1441. 20 Mbytes per year. 
  1442. Although we expect a substantial amount of buffer space to be available,
  1443. it is clear that high transaction rate systems will not be able to keep
  1444. all relevant portions of the XACT relation in main memory.  In this case,
  1445. the run-time cost to check whether individual transactions have been
  1446. committed will be prohibitive.  Hence, an
  1447. optional transaction accelerator which we now describe
  1448. will be a advantageous addition to POSTGRES.
  1449. .pp
  1450. We expect that virtually all of the transaction between T2 and
  1451. T3 will be committed transactions.  Consequently, we will use a second
  1452. XACT relation as a bloom filter [SEVR76] to detect aborted transactions
  1453. as follows.
  1454. XACT will have tuples of the form:
  1455. .(b
  1456. line-id        : the access method supplied ordering field
  1457. bitmap[M]    : a bit map of size M
  1458. .)b
  1459. For any aborted transaction with a XACTID between T2 and T3, the following
  1460. update must be performed.
  1461. Let N be the number of transactions allocated to each XACT record
  1462. and let LOW be T3 - remainder (T3/N).
  1463. .(b
  1464. replace XACT (bitmap[i] = 1) 
  1465. where XACT.line-id = (XACTID - LOW)modulo N
  1466. and i = hash (remainder ((XACTID - LOW) / N))
  1467. .)b
  1468. The vacuum process advances T3 periodically and deletes
  1469. tuples from XACT that correspond to transactions now older
  1470. than T3.  A second trigger will run periodically 
  1471. and advance T2 performing the above update for all aborted transactions
  1472. now older than T2.
  1473. .pp
  1474. Consequently, whenever the run-time system wishes to check whether
  1475. a candidate transaction, C-XACTID between T2 and T3 committed or aborted,
  1476. it examines 
  1477. .(b
  1478. bitmap[ hash (reaminder((C-XACTID - LOW) / N))]
  1479. .)b
  1480. If a zero is observed, then C-XACTID must have committed, otherwise
  1481. C-XACTID may have committed or aborted, and LOG must be examined to 
  1482. discover the true outcome.
  1483. .pp
  1484. The following analysis explores the performance of the 
  1485. transaction accelerator.  
  1486. .sh 3  "Analysis of the Accelerator"
  1487. .pp
  1488. Suppose B bits of main memory buffer space are available and
  1489. that M = 1000.  These B bits can either hold some (or all)
  1490. of LOG or they can hold some (or all) of XACT.  Moreover,
  1491. suppose transactions have a failure probability
  1492. of F, and N is chosen
  1493. so that X bits in bitmap are set on the average.  Hence, N = X / F.
  1494. In this case, a collection of
  1495. Q transactions will require Q bits in LOG and 
  1496. .(b
  1497. Q* F * 1000 / X
  1498. .)b
  1499. bits in the accelerator.  If this quantity is greater
  1500. than Q, the accelerator is useless because it takes up
  1501. more space than LOG.  Hence,
  1502. assume that
  1503. F * 1000 / X  << 1.  
  1504. In this case,
  1505. checking the disposition of a transaction in LOG will cause a page
  1506. fault 
  1507. with
  1508. probability:
  1509. .(b
  1510. FAULT (LOG) = 1 - [ B  / Q]
  1511. .)b
  1512. On the other hand, checking the disposition of
  1513. a transaction in the accelerator will cause a page fault with
  1514. probability:
  1515. .(b
  1516. P(XACT) = 1 - ( B * X) / (Q * F * 1000)
  1517. .)b
  1518. With probability
  1519. .(b
  1520. X / 1000
  1521. .)b
  1522. a ``1'' will be observed in the accelerator data structure.  If
  1523. .(b
  1524. B <  Q * F * 1000 / X
  1525. .)b  
  1526. then all available buffer space is consumed by the accelerator
  1527. and a
  1528. page fault will be assuredly generated to check in LOG if the
  1529. transaction committed or aborted.
  1530. Hence:
  1531. .(b
  1532. FAULT (XACT) = P(XACT) + X / 1000
  1533. .)b
  1534. If B is a larger value, then part of the buffer space can be
  1535. used for LOG, and FAULT decreases.
  1536. .pp
  1537. The difference in fault probability between the log
  1538. and the accelerator 
  1539. .(b
  1540. delta = FAULT (LOG) - FAULT (XACT) 
  1541. .)b
  1542. is maximized by choosing:
  1543. .(b
  1544. X = 1000 * square-root (F)
  1545. .)b
  1546. Figure 7 plots the expected number of faults in both systems for various
  1547. buffer sizes with this value for X.  
  1548. .(z
  1549. .hl
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.  
  1561.  
  1562.  
  1563.  
  1564.  
  1565. .sp
  1566. .ce
  1567. Figure 7. Expected number of faults versus buffer size.
  1568. .hl
  1569. .)z
  1570. As can be seen, the accelerator loses only when
  1571. there is a miniscule amount of buffer space or when there is nearly
  1572. enough to hold the whole log.  Moreover
  1573. .(b
  1574. size (XACT) = square-root (F) * size (LOG)
  1575. .)b
  1576. and if
  1577. .(b
  1578. B = size (XACT)
  1579. .)b
  1580. then the fault probability is lowered from 
  1581. .(b
  1582. FAULT (LOG) = 1 - square-root (F) 
  1583. .)b
  1584. to 
  1585. .(b
  1586. FAULT (XACT) = square-root (F)
  1587. .)b
  1588. If F = .01, then buffer requirements are reduced by a factor of 10 and
  1589. FAULT from .9 to .1.  Even when F = .1, XACT requires only 
  1590. one-third the buffer space, and cuts the fault probability in half.
  1591. .sh 3  "Transaction Management"
  1592. .pp
  1593. If a crash is observed for which the disk-based database
  1594. is intact, then all the recovery system must
  1595. do is advance T2 to be equal to T1 marking all 
  1596. transactions in progress at the time of the crash ``aborted.''
  1597. After this step, normal processing can commence.  It is
  1598. expected that recovery from ``soft'' crashes will be essentially
  1599. instantaneous.  
  1600. .pp
  1601. Protection from the perils of ``hard'' crashes, i.e. ones for
  1602. which the disk is not intact will be provided by mirroring
  1603. database files on magnetic disk either on a volume by volume basis
  1604. in hardware or on a file by file basis in software.
  1605. .pp
  1606. We envison a conventional two phase lock manager handling read and write locks
  1607. along with I, T and D locks.  It is expected that R and W locks will
  1608. be placed in a conventional main memory lock table, while other locks
  1609. will reside in data records.  The only
  1610. extension which we expect to implement is ``object locking.''  In this
  1611. situation, a user can declare that his stored procedures are to be
  1612. executed with no locking at all.  Of course, if two uses attempt
  1613. to execute a stored procedure at the same time, one will be blocked
  1614. because the first executor will place a write lock on the executed tuple.
  1615. In this way, if a collection of users is willing to guarantee that there
  1616. are no ``blind'' accesses to the pieces of objects (by someone
  1617. directly accessing
  1618. relations containing them), then they can be guaranteed consistency by
  1619. the placement of normal read and write locks on procedural objects and no locks
  1620. at all on the component objects.
  1621. .sh 3  "Access Methods"
  1622. .pp
  1623. We expect to implement both B-tree and OB-tree [STON83b]
  1624. secondary indexes.  Moreover,
  1625. our ADT facility supports an arbitrary
  1626. collection of user defined indexes.  
  1627. Each such index is, in reality, a pair of indexes one for magnetic disk
  1628. records and one for archival records.  The first index is of the form
  1629. .(b
  1630. index-relation (user-key-or-keys, pointer-to-tuple)
  1631. .)b
  1632. and uses the same structure as current INGRES secondary indexes.
  1633. The second index will have pointers to archival tuples and will
  1634. add ``tmin'' and ``tmax'' 
  1635. to whatever user keys are declared.  With this structure, records 
  1636. satisfying the qualification:
  1637. .(b
  1638. where relation.key = value
  1639. .)b
  1640. will be interpreted to mean:
  1641. .(b
  1642. where (relation[``now''].key = value)
  1643. .)b
  1644. and will require searching only the magnetic disk index.  General
  1645. queries of the form:
  1646. .(b
  1647. where relation[T].key = value
  1648. .)b
  1649. will require searching both the magnetic disk and the archival index.
  1650. Both indexes need only search for records with qualifying keys; moreover
  1651. the archival index can further restrict the search using tmax and tmin.
  1652. .pp
  1653. Any POSTQUEL replace command will 
  1654. insert a new data record with an appropriate BXID
  1655. and tmin, and then  
  1656. insert a record into all key indexes which are defined, and lastly change tmax
  1657. on the record to be updated.
  1658. A POSTQUEL append will only perform the first and third
  1659. steps while a delete only performs the second step.
  1660. Providing a pointer from the old tuple to the new tuple would allow
  1661. POSTGRES to insert records only into indexes for keys that are modified.
  1662. This optimization saves many disk writes at some expense in run-time
  1663. complexity.
  1664. We plan to implement this optimization.
  1665. .pp
  1666. The implementor of a new access method structure need only keep in mind that
  1667. the new data record must be forced from main
  1668. memory before any index records (or the index record will point to
  1669. garbage) and that multiple index updates (e.g. page splits) must be
  1670. forced in the correct order (i.e. from leaf to root).
  1671. This is easily accomplished with a single low level command to the
  1672. buffer manager:
  1673. .(b
  1674. order page1, page2
  1675. .)b
  1676. Inopportune crashes may leave an access method which consists
  1677. of a multi-level tree
  1678. with dangling index pages (i.e. pages that are not pointed two
  1679. from anywhere else in the tree).  Such crashes may also leave the
  1680. heap with 
  1681. uncommitted data records that cannot be reached from some indexes.
  1682. Such dangling tuples
  1683. will be garbage collected by the vacuum process
  1684. because they will have EXID equal to 
  1685. not committed.  Unfortunately if dangling data records are
  1686. not recorded in any index, then a sweep of memory will be periodicaly
  1687. required to find them.
  1688. Dangling index pages must be garbage collected by conventional
  1689. techniques.  
  1690. .pp
  1691. Ordered relations pose a special problem in our environment,
  1692. and we propose to change OB trees slightly to cope with the situation.
  1693. In particular, each place there is a counter in the original
  1694. proposal [STON83b] indicating the number of descendent tuple-identifiers, 
  1695. the counter must be replaced by the following:
  1696. .(b
  1697. counter-1    : same as counter
  1698. flag        : the danger bit
  1699. .)b
  1700. Any inserter or deleter in an OB tree will set the danger flag
  1701. whenever he updates counter-1.  Any OB tree accessor who reads
  1702. a data item with the danger flag set must interrupt the algorithm
  1703. and recompute counter-1 (by descending the tree).  Then he reascends
  1704. updating counter-1 and resetting the flag.  After this interlude,
  1705. he continues with his computation.  
  1706. In this way
  1707. the next transaction ``fixes up'' the structure left dangling by the
  1708. previous inserter or deleter, and OB-trees now work correctly.
  1709. .sh 3  "Vacuuming the Disk" 
  1710. .pp
  1711. Any record with BXID and EXID of committed can be written
  1712. to an optical disk or other long term repository.  
  1713. Moreover, any records with an BXID or EXID corresponding to
  1714. an aborted transaction can be discarded.  
  1715. The job of a ``vacuum'' demon is to perform these two tasks. Consequently,
  1716. the number of magnetic disk records is nearly equal to the number
  1717. with EXID equal to null (i.e. the magnetic disk holds the current 
  1718. ``state'' of the database).  The archival store holds historical
  1719. records, and the vacuum demon can ensure that ALL archival records
  1720. are valid.  Hence, the run-time POSTGRES system need never check
  1721. for the validity of archived records.  
  1722. .pp
  1723. The vacuum process will first write a historical record to the
  1724. archival store, then
  1725. insert a record in the
  1726. IID archival index, then insert a record in any archival 
  1727. key indexes, then delete the record from magnetic disk storage, and
  1728. finaly delete
  1729. the record from any magnetic disk indexes.
  1730. If a crash occurs, the vacuum process can simply
  1731. begin at the start of the sequence again.
  1732. .pp
  1733. If the vacuum process promptly archives historical records,
  1734. then one requires
  1735. disk space for the currently valid records
  1736. plus a small portion of the historical records  
  1737. (perhaps about 1.2 times the size of the currently valid database)
  1738. Additionally, one
  1739. should be able to maintain good physical clustering on the attribute
  1740. for which ordering is being attempted on the magnetic disk data set 
  1741. because there is constant
  1742. turnover of records.  
  1743. .pp
  1744. Some users may wish recently updated records to remain on magnetic disk
  1745. To accomplish this tuning, we propose to allow
  1746. a user to instruct the vacuum as follows:
  1747. .(b
  1748. vacuum rel-name where QUAL
  1749. .)b
  1750. A reasonable qualification might be:
  1751. .(b
  1752. vacuum rel-name where rel-name.tmax < now - 20 days
  1753. .)b
  1754. In this case, the vacuum demon would not remove records from the magnetic
  1755. disk representation of rel-name
  1756. until the qualification became true.
  1757. .sh 3  "Version Management"
  1758. .pp
  1759. Versions will be implemented by allocating a
  1760. differential file [SEVR76] for each separate version.
  1761. The differential file will contain the
  1762. tuples added to or subtracted from the base relation.
  1763. Secondary indexes will be built on versions 
  1764. to correspond to those
  1765. on the base relation from which the version is constructed.  
  1766. .pp
  1767. The algorithm to process POSTQUEL commands on versions is to begin with
  1768. the differential relation corresponding to the version itself.
  1769. For any tuple which satisfies the qualification, the v-IID
  1770. of the inspected tuple must be remembered 
  1771. on a list of ``seen IID's'' [WOOD83].  If a tuple with an IID on the
  1772. ``seen-id'' list is encountered, then it is discarded.  As long as tuples
  1773. can be inspected in reverse chronological order, one will always
  1774. notice the latest version of a tuple first, and then know to
  1775. discard earlier tuples.  If the version
  1776. is built on top of another version, then continue processing in the 
  1777. differential file of the next version.  Ultimately, a base relation will
  1778. be reached and the process will stop.  
  1779. .pp
  1780. If a tuple in a version is modified in the current version, then
  1781. it is treated as a normal update.  If an update to the current
  1782. version modifies a tuple in a previous version or the base
  1783. relation, then the IID of the replaced tuple will be placed in the
  1784. v-IID field and an appropriate tuple inserted into the differential
  1785. file for the version.  Deletes are handled in a similar fashion.  
  1786. .pp
  1787. To merge a version into a parent version 
  1788. then
  1789. one must perform the following steps for
  1790. each record in the new version valid at time T:
  1791. .ll -0.5i
  1792. .in +0.5i
  1793.  
  1794. 1) if it is an insert, then insert record into older version
  1795. .br
  1796. 2) if it is a delete, then delete the record in the older version
  1797. .br
  1798. 3) if it is a replace, then do an insert and a delete
  1799.  
  1800. .ll +0.5i
  1801. .in -0.5i
  1802. There is a conflict if one attempts to delete an already deleted
  1803. record.  Such cases must be handled external to the algorithm.
  1804. The tactics in [GARC84] may be helpful in reconciling these conflicts.
  1805. .pp
  1806. An older version can be rolled forward into a 
  1807. newer version by performing the above operations and
  1808. then renaming the older version.
  1809. .sh 1  "SUMMARY"
  1810. .pp
  1811. POSTGRES proposes to support complex objects by supporting an
  1812. extendible type system for defining new columns for relations,
  1813. new operators on these columns, and new access methods.  This
  1814. facility is appropriate for fairly ``simple'' complex objects.  More
  1815. complex objects, especially those with shared subobjects or multiple
  1816. levels of nesting, should use POSTGRES procedures as their
  1817. definition mechanism.  Procedures will be optimized by
  1818. caching compiled plans and even answers for retrieval commands.
  1819. .pp
  1820. Triggers and rules are supported as commands with ``always'' and ``demand''
  1821. modifiers.  They are efficiently supported by extensions to 
  1822. the locking system.  
  1823. Both forward chaining and backward chaining control structures
  1824. are
  1825. provided within the data manager using these mechanisms.  Our rules
  1826. system should prove attractive when there are multiple rules which
  1827. might apply in any given situation.
  1828. .pp
  1829. Crash recovery is simplified by not overwriting data and then vacuuming
  1830. tuples to an archive store.  The new storage system is greatly simplified
  1831. from current technology and supports time-oriented access and versions
  1832. with little difficulty.  The major cost of the storage system is the
  1833. requirement to push dirty pages of data to stable storage at commit time.
  1834. .pp
  1835. An optical disk is used effectively as an archival medium, and POSTGRES
  1836. has a collection of demons running in the background.  These can effectively
  1837. utilize otherwise idle processors.  Custom hardware could effectively provide
  1838. stable main memory, support for the LOG relation, and support for 
  1839. run-time checking of tuple validity.  
  1840. .pp
  1841. Lastly, these goals are accomplished with 
  1842. no changes to the relational model at all.
  1843. At the current time coding of POSTGRES is just beginning.  We hope
  1844. to have a prototype running in about a year.      
  1845. .bp
  1846. .ce
  1847. \fBREFERENCES\fP
  1848. .nr ii 10m
  1849. .ip [ADIB80]
  1850. Adiba, M.E. and Lindsay, B.G., ``Database Snapshots,''
  1851. IBM San Jose Res. Tech. Rep. RJ-2772, March 1980.
  1852. .ip [AFSA85]
  1853. Afasarmanesh, H., et. al., ``An Extensible Object-Oriented Approach to Database for VLSI/CAD,''
  1854. Proc. 1985 Very Large Data Base Conference, Stockholm, Sweden,
  1855. August 1985.
  1856. .ip [ALLM76] 
  1857. Allman, E., et. al., ``Embedding a Relational Data Sublanguage in a
  1858. General Purpose Programming Language,'' Proc 1976 ACM-SIGPLAN-SIGMOD
  1859. Conference on Data, Salt Lake City, Utah, March 1976.
  1860. .ip [ASTR76]
  1861. Astrhan, M. et. al., ``System R: A Relational Approach to Data,'' ACM-TODS,
  1862. June 1976.
  1863. .ip [ATKI84]
  1864. Atkinson, M.P. et. al., ``Progress with Persistent Programming,''
  1865. in Database, Role and Structure (ed. P. Stocker),
  1866. Cambridge Univeristy of Press, 1984.
  1867. .ip [BUNE79]
  1868. Bunemann, P. and Clemons, E., ``Efficiently Monitoring 
  1869. Relational Data Bases,'' ACM-TODS, Sept. 1979.
  1870. .ip [CLOC81] 
  1871. Clocksin, W.  and Mellish, C., ``Programming in Prolog,''
  1872. Springer-Verlag, Berlin, Germany, 1981.
  1873. .ip [CODD70]
  1874. Codd, E., ``A Relational Model of Data for Large Shared Data Bases,''
  1875. CACM, June 1970.
  1876. .ip [COPE84]
  1877. Copeland, G. and D. Maier, ``Making Smalltalk a Database System,''
  1878. Proc. 1984 ACM-SIGMOD Conference on Management of Data, Boston, Mass.
  1879. June 1984.
  1880. .ip [DERR85]
  1881. Derritt, N., Personal Communication, HP Laboratories, October 1985.
  1882. .ip [DEWI85]
  1883. DeWitt, D.J. and Carey, M.J., ``Extensible Database Systems,''
  1884. Proc. 1st International Workshop on Expert Data Bases, Kiowah, S.C., Oct 1984.
  1885. .ip [ESWA75] 
  1886. Eswaren, K., ``A General Purpose Trigger Subsystem and
  1887. Its Inclusion in a Relational Data Base System,''
  1888. IBM Research, San Jose, Ca., RJ 1833, July 1976.
  1889. .ip [GARC84]
  1890. Garcia-Molina, H., et. al., ``Data-Patch: Integrating Inconsistent copies of a 
  1891. Database after a Partition,'' Tech. Rep. TR# 304, Dept. Elec. Eng. and Comp. Sci.,
  1892. Princeton Univ., 1984.
  1893. .ip [HELD75]
  1894. Held, G. et. al., ``INGRES: A Relational Data Base System,'' Proc 1975 National
  1895. Computer Conference, Anaheim, Ca., June 1975.
  1896. .ip [GUTM84]
  1897. Gutman, A., ``R-trees: A Dynamic Index Structure for Spatial Searching,''
  1898. Proc. 1984 ACM-SIGMOD Conference on Management of Data, Boston, Mass.
  1899. June 1984.
  1900. .ip [JARK85]
  1901. Jarke, M. et. al.,  ``Data Constructors: On the Integration of Rules and Relations,'' 
  1902. Proc. 1985 Very Large Data Base Conference,
  1903. Stockholm, Sweden, August 1985.
  1904. .ip [KATZ85]
  1905. Katz, R.H., Information Management for Engineering Design, Springer-Verlag, 1985.
  1906. .ip [KUNG84]
  1907. Kung, R. et. al., ``Heuristic Search in Database Systems,'' Proc. 1st
  1908. International Workshop on Expert Data Bases, Kiowah, S.C., Oct 1984.
  1909. .ip [LORI83]
  1910. Lorie, R., and Plouffe, W., ``Complex Objects and Their Use in Desing Transactions,''
  1911. Proc. Eng. Design Applications of ACM-IEEE Data Base Week, San Jose, CA, May 1983.
  1912. .ip [LUM85]
  1913. Lum, V., et. al., ``Design of an Integrated DBMS to Support Advanced Applications,''
  1914. Proc. Int. Conf. on Foundations of Data Org., Kyoto Univ., Japan, May 1985.
  1915. .ip [ROBI81]
  1916. Robinson, J., ``The K-D-B Tree: A Search Structure for Large 
  1917. Multidimensional Indexes,'' Proc. 1981 ACM-SIGMOD Conference on
  1918. Management of Data, Ann Arbor, Mich., May 1981.
  1919. .ip [ROWE79]
  1920. Rowe, L.A. and Shoens, K., ``Data Abstraction, Views, and Updates in Rigel,''
  1921. Proc. 1979 ACM-SIGMOD Conference on Management of Data, Boston, MA, May 1979.
  1922. .ip [ROWE82]
  1923. Rowe, L.A. and Shoens, K. ``FADS - A Forms Application Development System,''
  1924. Proc. 1982 ACM-SIGMOD Conference on Management of Data, Orlando, FL, June 1982.
  1925. .ip [ROWE85]
  1926. Rowe, L., ``Fill-in-the-Form Programming,'' 
  1927. Proc. 1985 Very Large Data Base Conference, Stockholm, Sweden,
  1928. August 1985.
  1929. .ip [SELI79]
  1930. Selinger, P. et. al., ``Access Path Selection in a Relational
  1931. Data Base System,'' Proc 1979 ACM-SIGMOD Conference on Management
  1932. of Data, Boston, Mass., June 1979.
  1933. .ip [SEVR76]
  1934. Severence, D., and Lohman, G., ``Differential Files: Their Application
  1935. to the Maintenance of large Databases,'' ACM-TODS, June 1976.
  1936. .ip [STON75]
  1937. Stonebraker, M., ``Implementation of Integrity Constraints and
  1938. Views by Query Modification,'' Proc. 1975 ACM-SIGMOD Conference,
  1939. San Jose, Ca., May 1975.
  1940. .ip [STON76]
  1941. Stonebraker, M., et. al. ``The Design and Implementation of INGRES,''
  1942. ACM-TODS, September 1976.
  1943. .ip [STON81]
  1944. Stonebraker, M., ``Operating System Support for Database Management,''
  1945. CACM, July 1981.
  1946. .ip [STON83a]
  1947. Stonebraker, M., et. al., ``Performance Analysis of a Distributed Data
  1948. Base System,'' Proc. 3th Symposium on Reliability in Distributed
  1949. Software and Data Base Systems, Clearwater, Fla, Oct. 1983
  1950. .ip [STON83b]
  1951. Stonebraker, M., ``Document Processing in a Relational Database System,''
  1952. ACM TOOIS, April 1983. 
  1953. .ip [STON83c]
  1954. Stonebraker, M., et. al., ``Application of Abstract Data Types and Abstract
  1955. Indexes to CAD Data,'' Proc. Engineering Applications Stream of 1983 
  1956. Data Base Week, San Jose, Ca., May 1983.
  1957. .ip [STON84a]
  1958. Stonebraker, M. et. al., ``QUEL as a Data Type,'' Proc. 1984 ACM-SIGMOD
  1959. Conference on Management of Data, Boston, Mass., June 1984.
  1960. .ip [STON84b]
  1961. Stonebraker, M. and Rowe, L.A., ``PORTALS: A New Application Program Interface,''
  1962. Proc. 1984 VLDB Conference, Singapore, Sept 1984.
  1963. .ip [STON85a]
  1964. Stonebraker, M., ``Extending a Data Base System with Procedures,'' (submitted
  1965. for publication).
  1966. .ip [STON85b]
  1967. Stonebraker, M., ``Triggers and Inference in Data Base Systems,'' Proc. Islamoora
  1968. Conference on Expert Data Bases, Islamoora, Fla., Feb 1985, to appear as
  1969. a Springer-Verlag book.
  1970. .ip [STON85c]
  1971. Stonebraker, M. et. al., ``An Analysis of Rule Indexing Implementations
  1972. in Data Base Systems,'' (submitted for publication)
  1973. .ip [STON86]
  1974. Stonebraker, M., ``Inclusion of New Types in Relational Data Base Systems,''
  1975. Proc. Second International Conference on Data Base Engineering, Los Angeles,
  1976. Ca., Feb. 1986.
  1977. .ip [TICH82]
  1978. Tichy, W.F., ``Design, Implementation, and Evaluation of a Revision
  1979. Control System, Proc. 6th Int. Conf. on Soft. Eng., Sept 1982.
  1980. .ip [TSIC82]
  1981. Tsichritzis, D.C. ``Form Management,'' CACM 25, July 1982.
  1982. .ip [ULLM85] 
  1983. Ullman, J., ``Implementation of Logical Query Languages for Data Bases,''
  1984. Proceedings of the 1985 ACM-SIGMOD International Conference 
  1985. on Management of Data,
  1986. Austin, TX, May 1985.
  1987. .ip [WONG84] 
  1988. Wong, E., et al., ``Enhancing INGRES with Deductive Power,'' 
  1989. Proceedings of the 1st
  1990. International Workshop on Expert Data Base Systems, Kiowah SC,
  1991. October 1984.
  1992. .ip [WOOD83]
  1993. Woodfill, J. and Stonebraker, M., ``An Implementation of Hypothetical 
  1994. Relations,'' Proc. 9th VLDB Confernece, Florence, Italy, Dec. 1983.
  1995. .ip [ZANI83]
  1996. Zaniolo, C., ``The Database Language GEM,''
  1997. Proc. 1983 ACM-SIGMOD Conference on Management of Data,
  1998. San Jose, Ca., May 1983.
  1999.